import atexit
import logging
import sys
import threading
import time

import nacos
from django.apps import AppConfig

from algorithm import settings

logger = logging.getLogger(__name__)
server_addr = settings.NACOS_SERVER_ADDR
namespace = settings.NACOS_NAMESPACE
service_name = settings.NACOS_DATA_ID

class ApplicationConfig(AppConfig):
    default_auto_field = 'django.db.models.BigAutoField'
    name = 'application'
    nacos_client = None
    keep_running = True
    heartbeat_thread = None


    def ready(self):
        """当 Django 启动完成时调用"""
        # 仅在实际 WSGI 应用中运行（避免开发服务器重加载时多次运行）
        # if self.is_running_in_server():
        self.start_nacos_registration()

    def is_running_in_server(self):
        """检查是否运行在真实服务器环境中"""
        # 开发服务器检测
        if 'runserver' in sys.argv:
            return '--noreload' in sys.argv  # 只在非重载进程运行

        # 生产环境判断
        return True

    def start_nacos_registration(self):
        """注册服务并启动心跳管理"""
        try:
            # 创建 Nacos 客户端
            self.nacos_client = nacos.NacosClient(
                server_addresses=server_addr,
                namespace=namespace,
                # username="nacos",
                # password="nacos"
            )

            # 注册服务实例
            ip = self.get_local_ip()
            port = 8000  # 使用 settings.py 中的实际端口
            self.register_service(ip, port)

            # 启动心跳保持线程
            self.start_heartbeat_thread(ip, port)

            # 注册退出时的清理函数
            atexit.register(self.cleanup)
            logger.info("✅ Nacos 注册和心跳已启动")

        except Exception as e:
            logger.exception("❌ Nacos 初始化失败")

    def get_local_ip(self):
        """获取本机 IP 地址"""
        # 生产环境可能需要特定逻辑
        # 例如从环境变量获取或调用云服务 API
        import socket
        return socket.gethostbyname(socket.gethostname())

    def register_service(self, ip, port):
        """向 Nacos 注册服务"""
        self.nacos_client.add_naming_instance(
            service_name=service_name,
            ip=ip,
            port=port,
            cluster_name="DEFAULT",
            heartbeat_interval=5,
            metadata={"environment": "production"}
        )
        logger.info(f"🚀 服务已注册到 Nacos: {ip}:{port}")

    def start_heartbeat_thread(self, ip, port):
        """启动心跳保持线程"""

        def heartbeat_loop():
            """心跳循环（实际不需要发送，但用于异常检测）"""
            try:
                while self.keep_running:
                    # 检查服务状态（SDK会自动心跳）
                    time.sleep(15)
                    status = self.check_service_status(ip, port)
                    if not status:
                        logger.warning("Nacos 服务状态异常，尝试重新注册...")
                        self.register_service(ip, port)
            except Exception:
                logger.exception("心跳线程异常")

        # 启动守护线程（会随主线程退出）
        self.heartbeat_thread = threading.Thread(
            target=heartbeat_loop,
            daemon=True
        )
        self.heartbeat_thread.start()

    def check_service_status(self, ip, port):
        """检查服务在 Nacos 中的状态"""
        try:
            instances = self.nacos_client.list_naming_instance(service_name)
            for inst in instances.get('hosts', []):
                if inst['ip'] == ip and inst['port'] == port:
                    print("健康：{}".format(inst['healthy']))
                    return inst['healthy']
        except Exception as e:
            logger.error("获取服务状态失败")
        return False

    def cleanup(self):
        """清理资源：注销服务和停止线程"""
        self.keep_running = False
        try:
            if self.nacos_client:
                self.nacos_client.remove_naming_instance(
                    service_name,
                    self.get_local_ip(),
                    8000
                )
                logger.info("✅ 服务已从 Nacos 注销")
        except:
            logger.error("注销服务失败")
        finally:
            if self.heartbeat_thread and self.heartbeat_thread.is_alive():
                self.heartbeat_thread.join(timeout=5)
